/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package guzik.lukasz.SnpDataAPI.implementation;

import SnpDbEntities.Category;
import SnpDbEntities.Snippet;
import SnpDbEntities.User;
import SnpDbHndInterfaces.DBConnectable;
import guzik.lukasz.SnpDataAPI.SnpDataAPI;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Properties;

/**
 *
 * @author Łukasz 'byku' Guzik
 */
public class SnpDataAPIImpl extends SnpDataAPI
{
    private DBConnectable connection = null;
    private String sessionID = null;
    private LinkedHashMap<Integer, Category> privateCategoriesMap = null;
    private LinkedHashMap<Integer, Category> publicCategoriesMap = null;
    private LinkedHashMap<Integer, Snippet> privateSnippetsMap = null;
    private LinkedHashMap<Integer, Snippet> publicSnippetsMap = null;
    private LinkedHashMap<Integer, Snippet> snippetsToPublish = null;
    private LinkedHashMap<Integer, User> usersList = null;
    private User connectedUser = null;

    @Override
    public boolean connectAndAuth(String login, String password) throws
	    Exception
    {
	Properties props = new Properties();
	props.load(new FileInputStream("connection.properties"));
	String server = props.getProperty("server.address");

	if(connection != null)
	{
	    connection.disconnect(sessionID);
	}
	connection = (DBConnectable) java.rmi.Naming.lookup(server);
	sessionID = connection.connectAndAuth(login, User.calculateSHA1(password));

	if(sessionID != null)
	{
	    connectedUser = connection.getUserHandler(sessionID).getUser(login);
	    return true;
	} else
	{
	    connection = null;
	    return false;
	}
    }

    @Override
    public void disconnect()
    {
	connection = null;
	sessionID = null;
	connectedUser = null;
	privateCategoriesMap = null;
	privateSnippetsMap = null;
	publicCategoriesMap = null;
	publicSnippetsMap = null;
	snippetsToPublish = null;
	usersList = null;

	if(connection != null)
	{
	    try
	    {
		connection.disconnect(sessionID);
	    } catch(java.rmi.RemoteException e)
	    {
	    }
	}
    }

    @Override
    public User getConnectedUser()
    {
	if(connectedUser == null)
	{
	    return null;
	}

	User retVal = new User();
	retVal.setId(connectedUser.getId());
	retVal.setLogin(connectedUser.getLogin());
	retVal.setName(connectedUser.getName());
	retVal.setEmail(connectedUser.getEmail());
	retVal.setAbout(connectedUser.getAbout());
	retVal.setEnabled(true);
	retVal.setPermissions(connectedUser.getPermissions());

	return retVal;
    }

    @Override
    public LinkedHashMap<Integer, Category> getAllPrivateCategories()
    {
	if(privateCategoriesMap == null)
	{
	    try
	    {
		privateCategoriesMap = connection.getCatHandler(sessionID).getAllPrivateCategories();
	    } catch(java.rmi.RemoteException e)
	    {
		privateCategoriesMap = null;
	    }
	}
	return privateCategoriesMap;
    }

    @Override
    public LinkedHashMap<Integer, Category> getAllPublicCategories()
    {
	if(publicCategoriesMap == null)
	{
	    try
	    {
		publicCategoriesMap = connection.getCatHandler(sessionID).getAllPublicCategories();
	    } catch(java.rmi.RemoteException e)
	    {
		publicCategoriesMap = null;
	    }
	}
	return publicCategoriesMap;
    }

    @Override
    public LinkedHashMap<Integer, Snippet> getAllPrivateSnippets()
    {
	if(privateSnippetsMap == null)
	{
	    try
	    {
		privateSnippetsMap = connection.getSnpHandler(sessionID).getAllPrivateSnippets();
	    } catch(java.rmi.RemoteException e)
	    {
		privateSnippetsMap = null;
	    }
	}
	return privateSnippetsMap;
    }

    @Override
    public LinkedHashMap<Integer, Snippet> getAllPublicSnippets()
    {
	if(publicSnippetsMap == null)
	{
	    try
	    {
		publicSnippetsMap = connection.getSnpHandler(sessionID).getAllPublicSnippets();
	    } catch(java.rmi.RemoteException e)
	    {
		publicSnippetsMap = null;
	    }
	}
	return publicSnippetsMap;
    }

    @Override
    public Snippet getSnippetWithData(int snippetID, boolean isPublic)
    {
	try
	{
	    if(isPublic)
	    {
		return connection.getSnpHandler(sessionID).getPublicSnippet(snippetID, true);
	    } else
	    {
		return connection.getSnpHandler(sessionID).getPrivateSnippet(snippetID, true);
	    }
	} catch(java.rmi.RemoteException e)
	{
	    return null;
	}
    }

    @Override
    public User getUser(int userId)
    {
	try
	{
	    return connection.getUserHandler(sessionID).getUser(userId);
	} catch(java.rmi.RemoteException e)
	{
	    return null;
	}
    }

    @Override
    public int addCategory(Category newCat, boolean isPublic)
    {
	try
	{
	    if(isPublic)
	    {
		return connection.getCatHandler(sessionID).addPublicCategory(newCat);
	    } else
	    {
		return connection.getCatHandler(sessionID).addPrivateCategory(newCat);
	    }
	} catch(java.rmi.RemoteException e)
	{
	    return -1;
	}
    }

    @Override
    public boolean updateCategory(Category newCat, boolean isPublic)
    {
	try
	{
	    if(isPublic)
	    {
		return connection.getCatHandler(sessionID).updatePublicCategory(newCat);
	    } else
	    {
		return connection.getCatHandler(sessionID).updatePrivateCategory(newCat);
	    }
	} catch(java.rmi.RemoteException e)
	{
	    return false;
	}
    }

    @Override
    public boolean removeCategory(int catId, boolean isPublic)
    {
	try
	{
	    if(isPublic)
	    {
		return connection.getCatHandler(sessionID).deletePublicCategory(catId);
	    } else
	    {
		return connection.getCatHandler(sessionID).deletePrivateCategory(catId);
	    }
	} catch(java.rmi.RemoteException e)
	{
	    return false;
	}
    }

    @Override
    public int addPrivateSnippet(Snippet newSnp)
    {
	try
	{
	    return connection.getSnpHandler(sessionID).addPrivateSnippet(newSnp);
	} catch(java.rmi.RemoteException e)
	{
	    return -1;
	}
    }

    @Override
    public boolean updateSnippet(Snippet newSnp, boolean withData, boolean isPublic)
    {
	newSnp.setLastModified(new Date());
	try
	{
	    if(isPublic)
	    {
		return connection.getSnpHandler(sessionID).updatePublicSnippet(newSnp, withData);
	    } else
	    {
		return connection.getSnpHandler(sessionID).updatePrivateSnippet(newSnp, withData);
	    }
	} catch(java.rmi.RemoteException e)
	{
	    return false;
	}
    }

    @Override
    public boolean removePrivateSnippet(int snpId)
    {
	try
	{
	    return connection.getSnpHandler(sessionID).deletePrivateSnippet(snpId);
	} catch(java.rmi.RemoteException e)
	{
	    return false;
	}
    }

    @Override
    public boolean addToPublishQueue(int snpId, int publicCatId)
    {
	try
	{
	    return connection.getSnpHandler(sessionID).addToPublishQueue(snpId, publicCatId);
	} catch(java.rmi.RemoteException e)
	{
	    return false;
	}
    }

    @Override
    public boolean removeFromPublishQueue(int snpId)
    {
	try
	{
	    return connection.getSnpHandler(sessionID).removeFromPublishQueue(snpId);
	} catch(java.rmi.RemoteException e)
	{
	    return false;
	}
    }

    @Override
    public boolean publish(int snpId)
    {
	try
	{
	    return connection.getSnpHandler(sessionID).publish(snpId);
	} catch(java.rmi.RemoteException e)
	{
	    return false;
	}
    }

    @Override
    public boolean unpublish(int snpId)
    {
	try
	{
	    return connection.getSnpHandler(sessionID).unpublish(snpId);
	} catch(java.rmi.RemoteException e)
	{
	    return false;
	}
    }

    @Override
    public LinkedHashMap<Integer, Snippet> getSnippetsToPublish()
    {
	if(snippetsToPublish == null)
	{
	    try
	    {
		snippetsToPublish = connection.getSnpHandler(sessionID).getSnippetsToPublish();
	    } catch(java.rmi.RemoteException e)
	    {
		snippetsToPublish = null;
	    }
	}
	return snippetsToPublish;
    }

    @Override
    public ArrayList<Integer> getCategoryModerators(int catId)
    {
	try
	{
	    return connection.getCatHandler(sessionID).getCategoryModerators(catId);
	} catch(java.rmi.RemoteException e)
	{
	    return null;
	}
    }

    @Override
    public LinkedHashMap<Integer, User> getUsersList()
    {
	try
	{
	    if(usersList == null)
	    {
		usersList = connection.getUserHandler(sessionID).getUsersList();
	    }
	} catch(java.rmi.RemoteException e)
	{
	    usersList = null;
	} finally
	{
	    return usersList;
	}
    }

    @Override
    public int addUser(User newUser)
    {
	try
	{
	    return connection.getUserHandler(sessionID).addUser(newUser);
	} catch(java.rmi.RemoteException e)
	{
	    return -1;
	}
    }

    @Override
    public boolean updateUser(User newUserData)
    {
	try
	{
	    return connection.getUserHandler(sessionID).updateUser(newUserData);
	} catch(java.rmi.RemoteException e)
	{
	    return false;
	}
    }

    @Override
    public boolean removeUser(int userId)
    {
	try
	{
	    return connection.getUserHandler(sessionID).deleteUser(userId);
	} catch(Exception e)
	{
	    return false;
	}
    }

    @Override
    public boolean addModeratorToCategory(int modId, int catId)
    {
	try
	{
	    return connection.getCatHandler(sessionID).addModeratorToCategory(modId, catId);
	} catch(java.rmi.RemoteException e)
	{
	    return false;
	}
    }

    @Override
    public boolean removeModeratorFromCategory(int modId, int catId)
    {
	try
	{
	    return connection.getCatHandler(sessionID).removeModeratorFromCategory(modId, catId);
	} catch(java.rmi.RemoteException e)
	{
	    return false;
	}
    }
}
